package au.edu.qut.bpm.genbinder.util;

import java.util.List;
import org.deckfour.xes.extension.std.XConceptExtension;
import org.deckfour.xes.extension.std.XLifecycleExtension;
import org.deckfour.xes.extension.std.XOrganizationalExtension;
import org.deckfour.xes.extension.std.XSemanticExtension;
import org.deckfour.xes.extension.std.XTimeExtension;
import org.deckfour.xes.factory.XFactory;
import org.deckfour.xes.factory.XFactoryBufferedImpl;
import org.deckfour.xes.info.impl.XLogInfoImpl;
import org.deckfour.xes.model.XAttribute;
import org.deckfour.xes.model.XAttributeMap;
import org.deckfour.xes.model.XEvent;
import org.deckfour.xes.model.XLog;
import org.deckfour.xes.model.XTrace;

import au.edu.qut.bpm.genbinder.models.Activity;
import au.edu.qut.bpm.genbinder.models.Case;
import au.edu.qut.bpm.genbinder.models.ConcreteEventLog;
import au.edu.qut.bpm.genbinder.models.Resource;

public class LogToXESConverter {
	public static XLog createLog(ConcreteEventLog log, long startTime, long blockDuration) {
		XLog newLog = newLog(log.getAbstractLog().getId());
		XFactory xFactory = new XFactoryBufferedImpl();

		for (Case ca : log.getAbstractLog().getCases()) {
			List<Activity> sorted = log.getSortedTrace(ca);
			XTrace trace = xFactory.createTrace(ca.getAttributes());
			//System.err.println("size" + sorted.size());
			for (Activity ac : sorted) {
				XEvent start = xFactory.createEvent((XAttributeMap) ac.getAttributes().clone());
				XEvent stop = xFactory.createEvent((XAttributeMap) ac.getAttributes().clone());

				XConceptExtension.instance().assignName(start, ac.getTask().getId());
				XConceptExtension.instance().assignName(stop, ac.getTask().getId());

				XLifecycleExtension.instance().assignTransition(start, "start");
				XLifecycleExtension.instance().assignTransition(stop, "complete");

				String resourceString = "";
				boolean first = true;
				//System.err.println("res" + ac.getId() + "-" + log.getActivityResources(ac).toString());
				for (Resource r : log.getActivityResources(ac)) {
					if (!first)
						resourceString += ";";
					resourceString += r.getId();
					first = false;
				}
				XOrganizationalExtension.instance().assignResource(start, resourceString);
				XOrganizationalExtension.instance().assignResource(stop, resourceString);

				
				XTimeExtension.instance().assignTimestamp(start, startTime + blockDuration * log.getActivityStart(ac));
				XTimeExtension.instance().assignTimestamp(stop, startTime + blockDuration * log.getActivityEnd(ac));

				if (log.getActivityDuration(ac) > 0)
					trace.add(start);
				trace.add(stop);

				//System.err.println(start.getAttributes().get("lifecycle:transition").toString());
			}

			newLog.add(trace);
		}

		return newLog;
	}

	public static XLog newLog(String name) {
		XFactory xFactory = new XFactoryBufferedImpl();
		XLog log = xFactory.createLog();

		// Set extensions
		log.getExtensions().add(XConceptExtension.instance());
		log.getExtensions().add(XOrganizationalExtension.instance());
		log.getExtensions().add(XLifecycleExtension.instance());
		log.getExtensions().add(XSemanticExtension.instance());
		log.getExtensions().add(XTimeExtension.instance());

		// Set log classifiers
		log.getClassifiers().add(XLogInfoImpl.STANDARD_CLASSIFIER);
		log.getClassifiers().add(XLogInfoImpl.NAME_CLASSIFIER);
		log.getClassifiers().add(XLogInfoImpl.RESOURCE_CLASSIFIER);
		log.getClassifiers().add(XLogInfoImpl.LIFECYCLE_TRANSITION_CLASSIFIER);

		// Set guaranteed attributes
		log.getGlobalTraceAttributes().add((XAttribute) XConceptExtension.ATTR_NAME.clone());
		log.getGlobalEventAttributes().add((XAttribute) XConceptExtension.ATTR_NAME.clone());
		log.getGlobalEventAttributes().add((XAttribute) XLifecycleExtension.ATTR_TRANSITION.clone());

		XConceptExtension.instance().assignName(log, name);
		XLifecycleExtension.instance().assignModel(log, XLifecycleExtension.VALUE_MODEL_STANDARD);

		return log;
	}

}
